package com.fowo.api.flow.utils;

import cn.hutool.core.util.StrUtil;
import com.aliyun.dingtalkworkflow_1_0.Client;
import com.aliyun.dingtalkworkflow_1_0.models.*;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.models.RuntimeOptions;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiGettokenRequest;
import com.dingtalk.api.request.OapiProcessWorkrecordTaskCreateRequest;
import com.dingtalk.api.request.OapiV2UserGetbymobileRequest;
import com.dingtalk.api.response.OapiGettokenResponse;
import com.dingtalk.api.response.OapiProcessWorkrecordTaskCreateResponse;
import com.dingtalk.api.response.OapiV2UserGetbymobileResponse;
import com.fowo.api.common.model.R;
import com.fowo.api.flow.config.DingDingConfig;
import com.fowo.api.flow.entity.ProcessTemplates;
import com.fowo.api.flow.entity.WorkFlow;
import com.fowo.api.flow.service.FlowService;
import com.fowo.api.flow.service.ProcessTemplateService;
import com.fowo.api.flow.service.impl.WorkFlowServiceImpl;
import com.fowo.api.sys.entity.SysUser;
import com.fowo.api.sys.service.SysUserService;
import com.fowo.api.user.model.JwtUserInfo;
import com.fowo.api.util.LocalDateUtils;
import com.taobao.api.ApiException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

@Component
public class DingDingUtil {


    @Resource
    private ProcessTemplateService processTemplateService;

    @Resource
    private FlowService flowService;

    @Resource
    private WorkFlowServiceImpl workFlowService;


    @Resource
    private SysUserService userService;

    @Resource
    private DingDingConfig dingDingConfig;

    /**
     * 使用 Token 初始化账号Client
     *
     * @return Client
     * @throws Exception
     */
    public Client createClient() {
        Config config = new Config();
        config.protocol = "https";
        config.regionId = "central";
        try {
            return new Client(config);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取token
     *
     * @return
     * @throws ApiException
     */
    public String getToken() {
        DingTalkClient client = new DefaultDingTalkClient(StrUtil.concat(true, dingDingConfig.APPURL, "/gettoken"));
        OapiGettokenRequest req = new OapiGettokenRequest();
        req.setHttpMethod("GET");
        req.setAppkey(dingDingConfig.APPKEY);
        req.setAppsecret(dingDingConfig.APPSECRET);
        OapiGettokenResponse rsp = null;
        try {
            rsp = client.execute(req);
        } catch (ApiException e) {
            e.printStackTrace();
        }
        return rsp.getAccessToken();
    }


    /**
     * 获取用户id
     *
     * @return
     * @throws ApiException
     */
    public R<String> userInfo(String mobile) {
        DingTalkClient client = new DefaultDingTalkClient(StrUtil.concat(true, dingDingConfig.APPURL, "/topapi/v2/user/getbymobile"));
        OapiV2UserGetbymobileRequest req = new OapiV2UserGetbymobileRequest();
        req.setMobile(mobile);

        OapiV2UserGetbymobileResponse rsp = null;
        try {
            rsp = client.execute(req, getToken());
        } catch (ApiException e) {
            e.printStackTrace();
        }
        if (rsp.getErrcode() != 0) {
            return R.fail(rsp.getErrmsg());
        }

        String userid = rsp.getResult().getUserid();
        return R.data(userid);
    }


    public String saveProcess(String templateName, String remark, String processCode) {
        Client client = createClient();
        SaveProcessHeaders saveProcessHeaders = new SaveProcessHeaders();
        saveProcessHeaders.xAcsDingtalkAccessToken = getToken();


        // 1. 单行输入控件
        FormComponentProps formComponentProps1 = new FormComponentProps()
                .setComponentId("TextField-abcd")
                .setPlaceholder("请输入")
                .setLabel("日期")
                .setRequired(true);

        FormComponent formComponent1 = new FormComponent()
                .setComponentType("TextField")
                .setProps(formComponentProps1);
        SaveProcessRequest.SaveProcessRequestTemplateConfig templateConfig = new SaveProcessRequest.SaveProcessRequestTemplateConfig();
        templateConfig.setHidden(false)
                .setDisableSendCard(false);
        SaveProcessRequest saveProcessRequest = new SaveProcessRequest()
                .setName(templateName)
                .setDescription(remark)
                .setFormComponents(Arrays.asList(
                        formComponent1
                )).setTemplateConfig(templateConfig);
        if (StringUtils.isNotBlank(processCode)) {
            saveProcessRequest.setProcessCode(processCode);
        }

        SaveProcessResponse saveProcessResponse = null;
        try {
            saveProcessResponse = client.saveProcessWithOptions(saveProcessRequest, saveProcessHeaders, new RuntimeOptions());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return saveProcessResponse.getBody().getResult().getProcessCode();
    }


    /**
     * 更新状态
     *
     * @param wfId
     * @param result
     * @throws Exception
     */
    public void updateDingDingTask(String wfId, String result) {
        Client client = createClient();
        WorkFlow workFlow = workFlowService.getById(wfId);
        UpdateIntegratedTaskHeaders updateIntegratedTaskHeaders = new UpdateIntegratedTaskHeaders();
        updateIntegratedTaskHeaders.xAcsDingtalkAccessToken = getToken();
        UpdateIntegratedTaskRequest.UpdateIntegratedTaskRequestTasks tasks0 = new UpdateIntegratedTaskRequest.UpdateIntegratedTaskRequestTasks()
                .setTaskId(workFlow.getTaskId())
                .setStatus("COMPLETED")
                .setResult(result);
        UpdateIntegratedTaskRequest updateIntegratedTaskRequest = new UpdateIntegratedTaskRequest()
                .setProcessInstanceId(workFlow.getProcessInstanceId())
                .setTasks(java.util.Arrays.asList(
                        tasks0
                ));
        try {
            UpdateIntegratedTaskResponse updateIntegratedTaskResponse = client.updateIntegratedTaskWithOptions(updateIntegratedTaskRequest, updateIntegratedTaskHeaders, new RuntimeOptions());
        } catch (Exception e) {
            e.printStackTrace();
        }

    }


    /**
     * 创建钉钉实例
     *
     * @return
     * @throws Exception
     */
    public R<String> saveIntegratedInstance(String templateId, String userid) {
        ProcessTemplates processTemplates = processTemplateService.getById(templateId);
        if (ObjectUtils.isEmpty(processTemplates)) {
            return null;
        }
        if (StringUtils.isBlank(processTemplates.getProcessCode())) {
            return null;
        }
        SysUser user = userService.getById(userid);
        R<String> result = userInfo(user.getMobile());
        if (!result.isSuccess()) {
            return result;
        }
        String userId = result.getData();

        Client client = createClient();


        SaveIntegratedInstanceHeaders saveIntegratedInstanceHeaders = new SaveIntegratedInstanceHeaders();
        saveIntegratedInstanceHeaders.xAcsDingtalkAccessToken = getToken();
        SaveIntegratedInstanceRequest.SaveIntegratedInstanceRequestFormComponentValueList formComponentValueList0 = new SaveIntegratedInstanceRequest.SaveIntegratedInstanceRequestFormComponentValueList()
                .setName("日期")
                .setValue(LocalDateUtils.format(new Date(), LocalDateUtils.DATE_TIME_PATTERN));
        SaveIntegratedInstanceRequest saveIntegratedInstanceRequest = new SaveIntegratedInstanceRequest()
                .setFormComponentValueList(Arrays.asList(
                        formComponentValueList0
                ))
                .setProcessCode(processTemplates.getProcessCode())
                .setOriginatorUserId(userId)
                .setUrl("www.baidu.com");
        SaveIntegratedInstanceResponse saveIntegratedInstanceResponse = null;
        try {
            saveIntegratedInstanceResponse = client.saveIntegratedInstanceWithOptions(saveIntegratedInstanceRequest, saveIntegratedInstanceHeaders, new RuntimeOptions());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return R.data(saveIntegratedInstanceResponse.getBody().getResult().getProcessInstanceId());
    }

    /**
     * 创建流程中心待处理任务
     *
     * @param processInstanceId 实例id
     * @param wfId
     * @return
     * @throws Exception
     */
    public R<Long> createIntegratedTask(String processInstanceId, String wfId, String formName, Long recordId) {
        SysUser user = flowService.queryNodeUser(wfId);
        R<String> result = userInfo(user.getMobile());
        if (!result.isSuccess()) {
            return R.fail(result.getErrorMessage());
        }
        String userId = result.getData();

        JwtUserInfo currentUser = JwtUserInfo.fromHeader();
        String token = currentUser.toJwt();
        DingTalkClient client = new DefaultDingTalkClient(StrUtil.concat(true, dingDingConfig.APPURL, "/topapi/process/workrecord/task/create"));
        OapiProcessWorkrecordTaskCreateRequest req = new OapiProcessWorkrecordTaskCreateRequest();
        OapiProcessWorkrecordTaskCreateRequest.SaveTaskRequest obj1 = new OapiProcessWorkrecordTaskCreateRequest.SaveTaskRequest();
        obj1.setAgentid(1185599675L);
        obj1.setProcessInstanceId(processInstanceId);
        List<OapiProcessWorkrecordTaskCreateRequest.TaskTopVo> list3 = new ArrayList<OapiProcessWorkrecordTaskCreateRequest.TaskTopVo>();
        OapiProcessWorkrecordTaskCreateRequest.TaskTopVo obj4 = new OapiProcessWorkrecordTaskCreateRequest.TaskTopVo();
        list3.add(obj4);
        obj4.setUserid(userId);
        obj4.setUrl(dingDingConfig.H5URL + "/flowH5?formName=" + formName + "&recordId=" + recordId + "&token=" + token);
        obj1.setTasks(list3);
        req.setRequest(obj1);
        OapiProcessWorkrecordTaskCreateResponse rsp = null;
        try {
            rsp = client.execute(req, getToken());
        } catch (ApiException e) {
            e.printStackTrace();
        }

        return R.data(rsp.getTasks().get(0).getTaskId());
    }


}
